#pragma once
#include "QStandardItem"
#include "QTreeView"
#include "ViewItemDelegate.h"
#include <QVector3D>
#include <QtXml/QDomDocument>  
#include <QMutex>
#include "UIClass.h"
#include "MeshObjectBase.h"

class UITemplate
{
#ifdef USE_TEMPLATE
	ZMVector<SharedPointer<UIClassBase>> m_vUIClass;
#endif
	ZMVector<SharedPointer<UIDataBase>> m_vUIClass;
	QString m_templateID;
	QString m_scriptFileName;
	QString m_mainClassName;
	QString m_mainFunctionName;
	QString m_AttachFuncName;
	SharedPointer<MeshObjectBase> m_pMeshObject;
	int m_iMeshParamFrom;
	QString m_strRoadName;
public:
	~UITemplate() {};

	UITemplate() :m_iMeshParamFrom(0)
	{
	};

	UITemplate CopyTo() const;

	ZMVector<SharedPointer<UIDataBase>> GetParam() const;

	void AddParam(SharedPointer<UIDataBase> pParam);

	void SetParam(const ZMVector<SharedPointer<UIDataBase>>& vParam);


	void Clear();

	void CreateUI(QStandardItemModel* pModel, ViewItemDelegate*pDelegate, QModelIndex inxParent);

	void UpdateUI(QTreeView* pView, bool isToScreen, bool &isValueChange);

	QString GetTemplateID() const;

	void SetTemplateID(QString val);

	virtual void WriteBinaryData(CStreamSaveData& fp) const;

	void SetMeshObject(SharedPointer<MeshObjectBase> pMeshObject);
	
	void SetScriptInfo(QString scriptFileName, QString mainclass="ZMMainClass", QString mainFunc = "ZMMainFunc", QString strRoadName = "");

	bool IsMeshObjValid() const;

	ZMString UpdateShowMesh(OgreWidget * pWidget, const ZMString& meshName, const ZMString& parentNodeName, ZMVector<SharedPointer<UIDataBase>> vParamTranform= ZMVector<SharedPointer<UIDataBase>>());

	QString GetScriptFileName() const;

	QString GetRoadName() const { return m_strRoadName; }

	void SetRoadName(QString val) { m_strRoadName = val; }
protected:
	ZMVector<SharedPointer<UIDataBase>> GetMeshParam() const;
	ZMVector<SharedPointer<UIDataBase>> GetScriptParam() const;


};

class UIRelationTemplate
{
private:
	QString m_id;
	ZMVector<UITemplate> m_vTemplate;

	ZMVector<bool> m_vIsTemplateNeedUpdate;
	QString m_strDes;
public:
	bool IsNeedUpdate() const
	{
		bool ret = false;
		for (bool bData : m_vIsTemplateNeedUpdate)
		{
			if (bData)
			{
				ret = true;
				break;
			}
		}
		return ret;
	}

	void ResetUpdate()
	{
		for (int i = 0; i < m_vIsTemplateNeedUpdate.size(); ++i)
		{
			m_vIsTemplateNeedUpdate[i] = false;
		}
	}

	void CreateUI(QTreeView* pView, QStandardItemModel* pModel, ViewItemDelegate*pDelegate)
	{

		QModelIndex inxMain = UIDataBase::CreateDesRow(pDelegate, pModel, GetDes(), QModelIndex(), true).first;
		for (UITemplate& temp : m_vTemplate)
		{
			temp.CreateUI(pModel, pDelegate, inxMain);
		}


	}

	void UpdateUI(QTreeView* pView, bool isTOScreen)
	{
		for (int i = 0; i < m_vTemplate.size(); ++i)
		{
			bool bTemp;
			m_vTemplate[i].UpdateUI(pView, isTOScreen, bTemp);
			if (!isTOScreen && !m_vIsTemplateNeedUpdate[i])
			{
				m_vIsTemplateNeedUpdate[i] = bTemp;
			}
		}

	}

	QString GetId() const { return m_id; };

	void SetId(QString val) { m_id = val; };

	ZMVector<UITemplate> GetTemplate() const { return m_vTemplate; };

	void AddTemplate(UITemplate val, bool isNeedUpdate)
	{
		m_vTemplate.push_back(val);
		m_vIsTemplateNeedUpdate.push_back(isNeedUpdate);
	};

	void SetTemplate(const ZMVector<UITemplate>& val, const ZMVector<bool>& vIsNeedUpdate)
	{
		m_vTemplate = val;
		if (vIsNeedUpdate.size() != m_vTemplate.size())
		{
			m_vIsTemplateNeedUpdate.resize(m_vTemplate.size());

			for (int i = 0; i < m_vIsTemplateNeedUpdate.size(); ++i)
			{
				m_vIsTemplateNeedUpdate[i] = false;
			}
		}
		else
		{
			m_vIsTemplateNeedUpdate = vIsNeedUpdate;
		}
	};

	void Clear() { m_vTemplate.clear(); };

	QString GetDes() const { return m_strDes; }

	void SetDes(QString val) { m_strDes = val; };

	void WriteBinaryData(CStreamSaveData& fp) const
	{
		for (const UITemplate& pData : m_vTemplate)
		{
			pData.WriteBinaryData(fp);
		}
	}
};
typedef SharedPointer<UIRelationTemplate> PUIRelationTemplate;

class ObjRelationUI
{
	QString m_ObjName;

	ZMVector<PUIRelationTemplate> m_vpUIRelation;

	QString m_parentName;

	QString m_nodeParentName;

	ZMVector<SharedPointer<UIDataBase>>  m_vParam;

	QDate m_CompleteTime;
public:
	void AddParam(SharedPointer<UIDataBase> pParam)
	{
		m_vParam.push_back(pParam);
	}

	ZMVector<SharedPointer<UIDataBase>> GetParam()
	{
		return m_vParam;
	}

	QString GetObjName() const { return m_ObjName; }

	void SetObjName(QString val) { m_ObjName = val; }

	ZMVector<PUIRelationTemplate> GetUIRelation() const { return m_vpUIRelation; }

	void AddUIRelation(PUIRelationTemplate val) { m_vpUIRelation.push_back(val); }

	void SetUIRelation(ZMVector<PUIRelationTemplate> val) { m_vpUIRelation = val; }

	void Clear() { m_vpUIRelation.clear(); }

	void CreateUI(QTreeView* pView)
	{
		QStandardItemModel* pModel = new QStandardItemModel(pView);
		QStandardItemModel* pModelTemp = dynamic_cast<QStandardItemModel*>(pView->model());

		ViewItemDelegate*pDelegate = dynamic_cast<ViewItemDelegate*>(pView->itemDelegate());
		if (!pDelegate)
		{
			pDelegate = new ViewItemDelegate(pView);
			pView->setItemDelegate(pDelegate);
		}
		pDelegate->Clear();
		for (PUIRelationTemplate pTemplate : m_vpUIRelation)
		{
			pTemplate->CreateUI(pView, pModel, pDelegate);
		}
		pView->setModel(pModel);


		if (pModelTemp)
		{
			pModelTemp->clear();
			delete pModelTemp;
		}
	}

	void UpdateUI(QTreeView* pView, bool isTOScreen)
	{
		for (PUIRelationTemplate pTemplate : m_vpUIRelation)
		{
			bool bTemp;
			pTemplate->UpdateUI(pView, isTOScreen);
		}
	}

	virtual ZMVector<unsigned char> GetBinaryData() const
	{
		CStreamSaveData fp;
		for (const PUIRelationTemplate& pData : m_vpUIRelation)
		{
			pData->WriteBinaryData(fp);
		}
		fp.WriteBegin(m_ObjName);
		fp.Write("End Obj");
		return fp.GetBinaryData();
	}

	QString GetParentName() const { return m_parentName; }

	void SetParentName(QString val) { m_parentName = val; }
	
	QString GetParentNodeName() const { return m_nodeParentName; }
	
	void SetParentNodeName(QString val) { m_nodeParentName = val; }

	QDate GetCompleteTime() const { return m_CompleteTime; }

	void SetCompleteTime(QDate val) { m_CompleteTime = val; }
};